home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / libs / rawkey-0.2 / rawkey-0 / rawkey / rawkey.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-10-24  |  4.6 KB  |  267 lines

  1. /* librawkey v0.2 - (c) 1994 Russell Marks
  2.  * This library may be freely used/copied/modified provided this copyright
  3.  * notice is left intact.
  4.  *
  5.  * needs keymap support in kernel - been there since 0.99pl12 I think.
  6.  */
  7.  
  8. #include <stdio.h>
  9. #include <fcntl.h>
  10. #include <unistd.h>
  11. #include <signal.h>
  12. #include <termios.h>
  13. #include <sys/ioctl.h>
  14. #include <linux/kd.h>        /* RAW mode stuff, etc. */
  15. #include <linux/keyboard.h>    /* mainly for NR_KEYS */
  16. #include <linux/vt.h>        /* for VT stuff - nah, really? :) */
  17. #include "rawkey.h"
  18.  
  19.  
  20. static int keymap[NR_KEYS];    /* scancode -> ASCII translation */
  21. static int asciimap[256];    /* ASCII -> scancode translation */
  22. static int tty_fd=-1,restart_con=0,alt_pressed=0;
  23. static struct termios new_termio,old_termio;
  24. static int vtswitch_allowed=0;
  25.  
  26. static int key_down[128];
  27.  
  28. /* user-supplied functions to 'undraw' and 'redraw' screen
  29.  * if vt switching is allowed.
  30.  */
  31. void (*usermodeon)(void)=NULL;
  32. void (*usermodeoff)(void)=NULL;
  33.  
  34.  
  35. /* it's really easy to translate the scancodes these days, we just
  36.  * use the keytable stuff!
  37.  *
  38.  * returns 0 on error, 1 if ok
  39.  */
  40. int get_keyb_map()
  41. {
  42. struct kbentry keyb_ent;
  43. int f;
  44.  
  45. keyb_ent.kb_table=0;    /* unshifted */
  46. for(f=0;f<NR_KEYS;f++)
  47.   {
  48.   keyb_ent.kb_index=f;
  49.   
  50.   if(ioctl(tty_fd,KDGKBENT,(unsigned int)&keyb_ent))
  51.     return(0);
  52.     
  53.   keymap[f]=keyb_ent.kb_value;
  54.   }
  55. return(1);
  56. }
  57.  
  58.  
  59. void make_ascii_map()
  60. {
  61. int f,i,found;
  62.  
  63. for(f=0;f<256;f++)
  64.   {
  65.   found=0;
  66.   for(i=0;i<NR_KEYS;i++)
  67.     if((KTYP(keymap[i])==KT_LATIN || KTYP(keymap[i])==KT_LETTER ||
  68.         KTYP(keymap[i])==KT_ASCII) && KVAL(keymap[i])==f)
  69.       {
  70.       found=1;
  71.       break;
  72.       }
  73.       
  74.   asciimap[f]=found?i:-1;
  75.   }
  76. }
  77.  
  78.  
  79. void allow_switch(on)
  80. int on;
  81. {
  82. vtswitch_allowed=on;
  83. }
  84.  
  85.  
  86. void set_switch_functions(off,on)
  87. void (*off)(void);
  88. void (*on)(void);
  89. {
  90. usermodeoff=off;
  91. usermodeon=on;
  92. }
  93.  
  94.  
  95. void raw_mode(tty_fd,on)
  96. int tty_fd,on;
  97. {
  98. ioctl(tty_fd,KDSKBMODE,on?K_RAW:K_XLATE);
  99. }
  100.  
  101.  
  102. void blank_key_down()
  103. {
  104. int f;
  105.  
  106. for(f=0;f<NR_KEYS;f++)
  107.   key_down[f]=0;
  108. }
  109.  
  110.  
  111. void vt_from_here()
  112. {
  113. ioctl(tty_fd,TCSETSW,&old_termio);
  114. usermodeoff();
  115. raw_mode(tty_fd,0);  /* don't use rawmode_exit 'cos of other things it does */
  116. ioctl(tty_fd,VT_RELDISP,VT_ACKACQ);
  117. signal(SIGUSR1,vt_from_here);
  118. }
  119.  
  120.  
  121. void vt_to_here()
  122. {
  123. usermodeon();
  124. restart_con=1;        /* we're back, say to start up again */
  125. alt_pressed=0;
  126. raw_mode(tty_fd,1);
  127. signal(SIGUSR2,vt_to_here);
  128. }
  129.  
  130.  
  131. /* returns 1 if ok, 0 otherwise */
  132. int rawmode_init()
  133. {
  134. if(tty_fd==-1)
  135.   {
  136.   tty_fd=fileno(stdin);
  137.   fcntl(tty_fd,F_SETFL,O_NONBLOCK);
  138.   }
  139.  
  140. /* fix termio stuff so ^C-style interrupts are ignored */
  141. ioctl(tty_fd,TCGETS,&old_termio);
  142. new_termio=old_termio;
  143. new_termio.c_lflag&=~(ISIG|ICANON);
  144. ioctl(tty_fd,TCSETSW,&new_termio);
  145.  
  146. if(get_keyb_map(tty_fd,keymap))
  147.   {
  148.   struct vt_mode vtm;
  149.     
  150.   make_ascii_map();
  151.   blank_key_down();
  152.   raw_mode(tty_fd,1);
  153.   signal(SIGUSR1,vt_from_here);
  154.   signal(SIGUSR2,vt_to_here);
  155.   ioctl(tty_fd,VT_GETMODE,&vtm);
  156.   vtm.mode=VT_PROCESS;
  157.   vtm.relsig=SIGUSR1;
  158.   vtm.acqsig=SIGUSR2;
  159.   ioctl(tty_fd,VT_SETMODE,&vtm);
  160.   
  161.   return(1);
  162.   }
  163. else
  164.   return(0);
  165. }
  166.  
  167.  
  168. void rawmode_exit()
  169. {
  170. struct vt_mode vtm;
  171.  
  172. ioctl(tty_fd,VT_GETMODE,&vtm);
  173. vtm.mode=VT_AUTO;
  174. ioctl(tty_fd,VT_SETMODE,&vtm);
  175. ioctl(tty_fd,TCSETSW,&old_termio);
  176. raw_mode(tty_fd,0);
  177. tty_fd=-1;
  178. }
  179.  
  180.  
  181. /* returns -1 if no keypresses pending, else returns scancode. */
  182. int get_scancode()
  183. {
  184. unsigned char c;
  185.  
  186. if(read(tty_fd,&c,1)<=0)
  187.   return(-1);
  188.  
  189. return((int)c);
  190. }
  191.  
  192.  
  193. int is_key_pressed(sc)
  194. int sc;
  195. {
  196. if(sc<0 || sc>127) return(0);
  197. return(key_down[sc]?1:0);
  198. }
  199.  
  200.  
  201. int is_any_key_pressed()
  202. {
  203. int f;
  204.  
  205. for(f=0;f<128;f++)
  206.   if(key_down[f]) return(1);
  207.  
  208. return(0);
  209. }
  210.  
  211.  
  212. /* this is the routine you should call whenever you would normally
  213.  * read a keypress. However, to actually tell if a key is pressed,
  214.  * call is_key_pressed() with a scancode as arg.
  215.  */
  216. void scan_keyboard()
  217. {
  218. int c,key,flag,vt;
  219.  
  220. /* we use BFI to fix the PrtSc/Pause problem - i.e. we don't :^) */
  221. while((c=get_scancode())==0xE0);
  222. if(c==0xE1) c=get_scancode();
  223.  
  224. if(c==-1) return;    /* no key was pressed */
  225.  
  226. key=c&127;
  227. flag=(c&128)?0:1;    /* 1 = down */
  228.  
  229. key_down[key]=flag;
  230.  
  231. if(key==LEFT_ALT) alt_pressed=!flag;
  232.  
  233. if(alt_pressed && c>=FUNC_KEY(1) && c<=FUNC_KEY(10))
  234.   {
  235.   struct vt_stat vts;
  236.   int newvt;
  237.   
  238.   ioctl(tty_fd,VT_GETSTATE,&vts);
  239.   newvt=c-FUNC_KEY(1)+1;
  240.   if(vts.v_active!=newvt && vtswitch_allowed &&
  241.       usermodeoff!=NULL && usermodeon!=NULL)
  242.     {
  243.     ioctl(tty_fd,VT_ACTIVATE,newvt);
  244.     restart_con=0;
  245.     while(restart_con==0) usleep(50000);
  246.     }
  247.   }
  248. }
  249.  
  250.  
  251. /* converts scancode to key binding */
  252. int keymap_trans(sc)
  253. int sc;
  254. {
  255. if(sc<0 || sc>127) return(-1);
  256. return(keymap[sc]);
  257. }
  258.  
  259.  
  260. /* converts ASCII to scancode */
  261. int scancode_trans(asc)
  262. int asc;
  263. {
  264. if(asc<0 || asc>255) return(-1);
  265. return(asciimap[asc]);
  266. }
  267.